Micron Document
NexusPi Git Node

Node / mirrors / RTNode-HeltecV4 / files / docs / index.html

Displaying Raw • Download

docs/index.html main (ee519cc2) Text, 24.82 KB

Tff7b72<!DOCTYPE html>
Tb4b4b4<Tff7b72html Te6edf3langTff7b72=Ta5d6ff"en"Tb4b4b4>
Tb4b4b4<Tff7b72headTb4b4b4>
Tb4b4b4<Tff7b72meta Te6edf3charsetTff7b72=Ta5d6ff"UTF-8"Tb4b4b4>
Tb4b4b4<Tff7b72meta Te6edf3nameTff7b72=Ta5d6ff"viewport" Te6edf3contentTff7b72=Ta5d6ff"width=device-width, initial-scale=1.0"Tb4b4b4>
Tb4b4b4<Tff7b72titleTb4b4b4>RTNode Firmware FlasherTb4b4b4<Tb4b4b4/Tff7b72titleTb4b4b4>
Tb4b4b4<Tff7b72styleTb4b4b4>
Tff7b72*Tff7b72, Tff7b72*Tb4b4b4::Tf0883ebeforeTff7b72, Tff7b72*Tb4b4b4::Tf0883eafter Tb4b4b4{ Tff7b72box-sizingTb4b4b4: Tff7b72border-boxTb4b4b4; Tff7b72marginTb4b4b4: T79c0ff0Tb4b4b4; Tff7b72paddingTb4b4b4: T79c0ff0Tb4b4b4; Tb4b4b4}

Tb4b4b4:Tf0883eroot Tb4b4b4{
Te6edf3--bgTb4b4b4: T79c0ff#0f1117Tb4b4b4;
Te6edf3--surfaceTb4b4b4: T79c0ff#1a1d27Tb4b4b4;
Te6edf3--borderTb4b4b4: T79c0ff#2a2d3aTb4b4b4;
Te6edf3--accentTb4b4b4: T79c0ff#5b8af5Tb4b4b4;
Te6edf3--accent-hiTb4b4b4: T79c0ff#7ba3ffTb4b4b4;
Te6edf3--successTb4b4b4: T79c0ff#4caf76Tb4b4b4;
Te6edf3--warnTb4b4b4: T79c0ff#e0a742Tb4b4b4;
Te6edf3--textTb4b4b4: T79c0ff#e2e4efTb4b4b4;
Te6edf3--mutedTb4b4b4: T79c0ff#8a8fa8Tb4b4b4;
Te6edf3--radiusTb4b4b4: T79c0ff10Tffa657pxTb4b4b4;
Tb4b4b4}

Tff7b72body Tb4b4b4{
Tff7b72font-familyTb4b4b4: Tff7b72-Te6edf3apple-systemTb4b4b4, Te6edf3BlinkMacSystemFontTb4b4b4, Ta5d6ff"Segoe UI"Tb4b4b4, Tff7b72sans-serifTb4b4b4;
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--bgTb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--textTb4b4b4)Tb4b4b4;
Tff7b72min-heightTb4b4b4: T79c0ff100Tffa657vhTb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff2Tffa657rem T79c0ff1Tffa657rem T79c0ff4Tffa657remTb4b4b4;
Tff7b72line-heightTb4b4b4: T79c0ff1.6Tb4b4b4;
Tb4b4b4}

Tff7b72main Tb4b4b4{ Tff7b72max-widthTb4b4b4: T79c0ff680Tffa657pxTb4b4b4; Tff7b72marginTb4b4b4: T79c0ff0 Tff7b72autoTb4b4b4; Tb4b4b4}

T8b949e/* ── Header ─────────────────────────────────────────── */
Tff7b72header Tb4b4b4{ Tff7b72text-alignTb4b4b4: Tff7b72centerTb4b4b4; Tff7b72margin-bottomTb4b4b4: T79c0ff3Tffa657remTb4b4b4; Tb4b4b4}
Tff7b72header Tff7b72h1 Tb4b4b4{
Tff7b72font-sizeTb4b4b4: T79c0ff2Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff700Tb4b4b4;
Tff7b72letter-spacingTb4b4b4: T79c0ff-0.5Tffa657pxTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--textTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72header Tff7b72h1 Tff7b72span Tb4b4b4{ Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4; Tb4b4b4}
Tff7b72header Tff7b72p Tb4b4b4{ Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4; Tff7b72margin-topTb4b4b4: T79c0ff0.4Tffa657remTb4b4b4; Tff7b72font-sizeTb4b4b4: T79c0ff0.95Tffa657remTb4b4b4; Tb4b4b4}

T8b949e/* ── Steps ──────────────────────────────────────────── */
Tb4b4b4.T56d364step Tb4b4b4{ Tff7b72margin-bottomTb4b4b4: T79c0ff2.2Tffa657remTb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364step-label Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72align-itemsTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.6Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.78Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff700Tb4b4b4;
Tff7b72letter-spacingTb4b4b4: T79c0ff1.5Tffa657pxTb4b4b4;
Tff7b72text-transformTb4b4b4: Tff7b72uppercaseTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4;
Tff7b72margin-bottomTb4b4b4: T79c0ff0.8Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364step-labelTb4b4b4::Tf0883eafter Tb4b4b4{
Tff7b72contentTb4b4b4: Ta5d6ff''Tb4b4b4;
Tff7b72flexTb4b4b4: T79c0ff1Tb4b4b4;
Tff7b72heightTb4b4b4: T79c0ff1Tffa657pxTb4b4b4;
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/* ── Flash button ─────────────────────────────────── */
Tb4b4b4.T56d364flash-btn Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72inline-flexTb4b4b4;
Tff7b72align-itemsTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.5Tffa657remTb4b4b4;
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: T79c0ff#fffTb4b4b4;
Tff7b72borderTb4b4b4: Tff7b72noneTb4b4b4;
Tff7b72border-radiusTb4b4b4: T79c0ff8Tffa657pxTb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff0.7Tffa657rem T79c0ff1.6Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff1Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff600Tb4b4b4;
Tff7b72cursorTb4b4b4: Tff7b72pointerTb4b4b4;
Tff7b72transitionTb4b4b4: Tff7b72background T79c0ff0.15Tffa657sTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364flash-btnTb4b4b4:Tf0883ehoverTb4b4b4:Tf0883enotTff7b72(Tb4b4b4:Tf0883edisabledTff7b72) Tb4b4b4{ Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accent-hiTb4b4b4)Tb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364flash-btnTb4b4b4:Tf0883edisabled Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72cursorTb4b4b4: Tff7b72not-allowedTb4b4b4;
Tff7b72opacityTb4b4b4: T79c0ff0.7Tb4b4b4;
Tb4b4b4}

T8b949e/* ── Detect badge ────────────────────────────────────── */
Tb4b4b4.T56d364detect-badge Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72align-itemsTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.5Tffa657remTb4b4b4;
Tff7b72border-radiusTb4b4b4: T79c0ff6Tffa657pxTb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff0.4Tffa657rem T79c0ff0.75Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.83Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff600Tb4b4b4;
Tff7b72margin-bottomTb4b4b4: T79c0ff0.9Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364detect-badgeTb4b4b4.T56d364ok Tb4b4b4{
Tff7b72backgroundTb4b4b4: Tffa657rgbaTb4b4b4(T79c0ff76Tb4b4b4, T79c0ff175Tb4b4b4, T79c0ff118Tb4b4b4, T79c0ff0.12Tb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Tffa657rgbaTb4b4b4(T79c0ff76Tb4b4b4, T79c0ff175Tb4b4b4, T79c0ff118Tb4b4b4, T79c0ff0.3Tb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--successTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364detect-badgeTb4b4b4.T56d364err Tb4b4b4{
Tff7b72backgroundTb4b4b4: Tffa657rgbaTb4b4b4(T79c0ff229Tb4b4b4, T79c0ff115Tb4b4b4, T79c0ff115Tb4b4b4, T79c0ff0.1Tb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Tffa657rgbaTb4b4b4(T79c0ff229Tb4b4b4, T79c0ff115Tb4b4b4, T79c0ff115Tb4b4b4, T79c0ff0.3Tb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: T79c0ff#e57373Tb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364detect-badgeTb4b4b4.T56d364info Tb4b4b4{
Tff7b72backgroundTb4b4b4: Tffa657rgbaTb4b4b4(T79c0ff91Tb4b4b4, T79c0ff138Tb4b4b4, T79c0ff245Tb4b4b4, T79c0ff0.1Tb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Tffa657rgbaTb4b4b4(T79c0ff91Tb4b4b4, T79c0ff138Tb4b4b4, T79c0ff245Tb4b4b4, T79c0ff0.25Tb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/* ── Progress ────────────────────────────────────────── */
Tb4b4b4.T56d364progress-wrap Tb4b4b4{ Tff7b72marginTb4b4b4: T79c0ff0.75Tffa657rem T79c0ff0Tb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364progress-track Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72border-radiusTb4b4b4: T79c0ff4Tffa657pxTb4b4b4;
Tff7b72heightTb4b4b4: T79c0ff6Tffa657pxTb4b4b4;
Tff7b72overflowTb4b4b4: Tff7b72hiddenTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364progress-fill Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4;
Tff7b72heightTb4b4b4: T79c0ff100Tffa657%Tb4b4b4;
Tff7b72widthTb4b4b4: T79c0ff0Tffa657%Tb4b4b4;
Tff7b72transitionTb4b4b4: Tff7b72width T79c0ff0.15Tffa657sTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364progress-pct Tb4b4b4{
Tff7b72font-sizeTb4b4b4: T79c0ff0.78Tffa657remTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72margin-topTb4b4b4: T79c0ff0.3Tffa657remTb4b4b4;
Tb4b4b4}

T8b949e/* ── Log area ────────────────────────────────────────── */
Tb4b4b4.T56d364log-area Tb4b4b4{
Tff7b72backgroundTb4b4b4: Tffa657rgbaTb4b4b4(T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0Tb4b4b4,T79c0ff0.35Tb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72border-radiusTb4b4b4: T79c0ff6Tffa657pxTb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff0.55Tffa657rem T79c0ff0.8Tffa657remTb4b4b4;
Tff7b72font-familyTb4b4b4: Te6edf3ui-monospaceTb4b4b4, Ta5d6ff"Cascadia Code"Tb4b4b4, Tff7b72monospaceTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.76Tffa657remTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72max-heightTb4b4b4: T79c0ff150Tffa657pxTb4b4b4;
Tff7b72overflow-yTb4b4b4: Tff7b72autoTb4b4b4;
Tff7b72margin-topTb4b4b4: T79c0ff0.9Tffa657remTb4b4b4;
Tff7b72white-spaceTb4b4b4: Tff7b72pre-wrapTb4b4b4;
Tff7b72word-breakTb4b4b4: Te6edf3break-allTb4b4b4;
Tb4b4b4}
T8b949e/* ── Mode toggle ────────────────────────────────────── */
Tb4b4b4.T56d364mode-toggle Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0Tb4b4b4;
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--surfaceTb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72border-radiusTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--radiusTb4b4b4)Tb4b4b4;
Tff7b72overflowTb4b4b4: Tff7b72hiddenTb4b4b4;
Tff7b72margin-bottomTb4b4b4: T79c0ff1.1Tffa657remTb4b4b4;
Tff7b72widthTb4b4b4: T79c0ff100Tffa657%Tb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364mode-btn Tb4b4b4{
Tff7b72flexTb4b4b4: T79c0ff1Tb4b4b4;
Tff7b72backgroundTb4b4b4: Tff7b72noneTb4b4b4;
Tff7b72borderTb4b4b4: Tff7b72noneTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff0.6Tffa657rem T79c0ff0.5Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.85Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff600Tb4b4b4;
Tff7b72cursorTb4b4b4: Tff7b72pointerTb4b4b4;
Tff7b72transitionTb4b4b4: Tff7b72background T79c0ff0.15Tffa657sTb4b4b4, Tff7b72color T79c0ff0.15Tffa657sTb4b4b4;
Tff7b72text-alignTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72line-heightTb4b4b4: T79c0ff1.3Tb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364mode-btnTb4b4b4:Tf0883efirst-child Tb4b4b4{ Tff7b72border-rightTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364mode-btnTb4b4b4.T56d364active Tb4b4b4{
Tff7b72backgroundTb4b4b4: T79c0ff#1c2340Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--textTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364mode-btn Tb4b4b4.T56d364mode-sub Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72blockTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.72Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff400Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72margin-topTb4b4b4: T79c0ff1Tffa657pxTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364mode-btnTb4b4b4.T56d364active Tb4b4b4.T56d364mode-sub Tb4b4b4{ Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4; Tb4b4b4}

T8b949e/* ── Version picker ──────────────────────────────────── */
Tb4b4b4.T56d364version-row Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72align-itemsTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.75Tffa657remTb4b4b4;
Tff7b72margin-bottomTb4b4b4: T79c0ff1.1Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364version-row Tff7b72label Tb4b4b4{
Tff7b72font-sizeTb4b4b4: T79c0ff0.85Tffa657remTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff600Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72white-spaceTb4b4b4: Tff7b72nowrapTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364version-row Tff7b72select Tb4b4b4{
Tff7b72flexTb4b4b4: T79c0ff1Tb4b4b4;
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--bgTb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72border-radiusTb4b4b4: T79c0ff6Tffa657pxTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--textTb4b4b4)Tb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff0.45Tffa657rem T79c0ff2.2Tffa657rem T79c0ff0.45Tffa657rem T79c0ff0.75Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.85Tffa657remTb4b4b4;
Tff7b72font-familyTb4b4b4: Tff7b72inheritTb4b4b4;
Tff7b72cursorTb4b4b4: Tff7b72pointerTb4b4b4;
Tff7b72appearanceTb4b4b4: Tff7b72noneTb4b4b4;
Tff7b72background-imageTb4b4b4: Tffa657urlTb4b4b4(Ta5d6ff"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath stroke='%238a8fa8' stroke-width='1.5' fill='none' d='M1 1l4 4 4-4'/%3E%3C/svg%3E"Tb4b4b4)Tb4b4b4;
Tff7b72background-repeatTb4b4b4: Tff7b72no-repeatTb4b4b4;
Tff7b72background-positionTb4b4b4: Tff7b72right T79c0ff0.75Tffa657rem Tff7b72centerTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364version-row Tff7b72selectTb4b4b4:Tf0883efocus Tb4b4b4{ Tff7b72outlineTb4b4b4: Tff7b72noneTb4b4b4; Tff7b72border-colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364version-row Tff7b72selectTb4b4b4:Tf0883edisabled Tb4b4b4{ Tff7b72opacityTb4b4b4: T79c0ff0.5Tb4b4b4; Tff7b72cursorTb4b4b4: Tff7b72not-allowedTb4b4b4; Tb4b4b4}

T8b949e/* ── Flash section ──────────────────────────────────── */
Tb4b4b4.T56d364flash-box Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--surfaceTb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72border-radiusTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--radiusTb4b4b4)Tb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff1.4Tffa657rem T79c0ff1.6Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364flash-box Tff7b72p Tb4b4b4{ Tff7b72font-sizeTb4b4b4: T79c0ff0.9Tffa657remTb4b4b4; Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4; Tff7b72margin-bottomTb4b4b4: T79c0ff1.1Tffa657remTb4b4b4; Tb4b4b4}



T8b949e/* ── Requirements ───────────────────────────────────── */
Tb4b4b4.T56d364req-list Tb4b4b4{
Tff7b72list-styleTb4b4b4: Tff7b72noneTb4b4b4;
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72flex-directionTb4b4b4: Tff7b72columnTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.5Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364req-list Tff7b72li Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72align-itemsTb4b4b4: Tff7b72flex-startTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.6Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.9Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364req-list Tff7b72li Tb4b4b4.T56d364icon Tb4b4b4{ Tff7b72flex-shrinkTb4b4b4: T79c0ff0Tb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364req-list Tff7b72li Tb4b4b4.T56d364ok Tb4b4b4{ Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--successTb4b4b4)Tb4b4b4; Tb4b4b4}
Tb4b4b4.T56d364req-list Tff7b72li Tb4b4b4.T56d364warn Tb4b4b4{ Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--warnTb4b4b4)Tb4b4b4; Tb4b4b4}

T8b949e/* ── Flash size note ────────────────────────────────── */
Tff7b72details Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--surfaceTb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72border-radiusTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--radiusTb4b4b4)Tb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff0.8Tffa657rem T79c0ff1.1Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.88Tffa657remTb4b4b4;
Tb4b4b4}
Tff7b72summary Tb4b4b4{
Tff7b72cursorTb4b4b4: Tff7b72pointerTb4b4b4;
Tff7b72font-weightTb4b4b4: T79c0ff600Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tff7b72list-styleTb4b4b4: Tff7b72noneTb4b4b4;
Tff7b72user-selectTb4b4b4: Tff7b72noneTb4b4b4;
Tb4b4b4}
Tff7b72summaryTb4b4b4::Tf0883e-webkit-details-marker Tb4b4b4{ Tff7b72displayTb4b4b4: Tff7b72noneTb4b4b4; Tb4b4b4}
Tff7b72summaryTb4b4b4::Tf0883ebefore Tb4b4b4{ Tff7b72contentTb4b4b4: Ta5d6ff"▶ "Tb4b4b4; Tff7b72font-sizeTb4b4b4: T79c0ff0.7Tffa657emTb4b4b4; Tb4b4b4}
Tff7b72detailsTff7b72[Tff7b72openTff7b72] Tff7b72summaryTb4b4b4::Tf0883ebefore Tb4b4b4{ Tff7b72contentTb4b4b4: Ta5d6ff"▼ "Tb4b4b4; Tb4b4b4}
Tff7b72details Tff7b72p Tb4b4b4{ Tff7b72margin-topTb4b4b4: T79c0ff0.7Tffa657remTb4b4b4; Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4; Tff7b72line-heightTb4b4b4: T79c0ff1.6Tb4b4b4; Tb4b4b4}
Tff7b72details Tff7b72code Tb4b4b4{
Tff7b72backgroundTb4b4b4: Tffa657rgbaTb4b4b4(T79c0ff255Tb4b4b4,T79c0ff255Tb4b4b4,T79c0ff255Tb4b4b4,T79c0ff0.07Tb4b4b4)Tb4b4b4;
Tff7b72paddingTb4b4b4: T79c0ff1Tffa657px T79c0ff5Tffa657pxTb4b4b4;
Tff7b72border-radiusTb4b4b4: T79c0ff4Tffa657pxTb4b4b4;
Tff7b72font-familyTb4b4b4: Te6edf3ui-monospaceTb4b4b4, Tff7b72monospaceTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.9Tffa657emTb4b4b4;
Tb4b4b4}

T8b949e/* ── Button row ───────────────────────────────────────── */
Tb4b4b4.T56d364btn-row Tb4b4b4{
Tff7b72displayTb4b4b4: Tff7b72flexTb4b4b4;
Tff7b72gapTb4b4b4: T79c0ff0.75Tffa657remTb4b4b4;
Tff7b72align-itemsTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72flex-wrapTb4b4b4: Tff7b72wrapTb4b4b4;
Tff7b72margin-topTb4b4b4: T79c0ff0.25Tffa657remTb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364flash-btnTb4b4b4.T56d364secondary Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--surfaceTb4b4b4)Tb4b4b4;
Tff7b72borderTb4b4b4: T79c0ff1Tffa657px Tff7b72solid Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4.T56d364flash-btnTb4b4b4.T56d364secondaryTb4b4b4:Tf0883ehoverTb4b4b4:Tf0883enotTff7b72(Tb4b4b4:Tf0883edisabledTff7b72) Tb4b4b4{
Tff7b72backgroundTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--borderTb4b4b4)Tb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--textTb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e/* ── Footer ─────────────────────────────────────────── */
Tff7b72footer Tb4b4b4{
Tff7b72text-alignTb4b4b4: Tff7b72centerTb4b4b4;
Tff7b72margin-topTb4b4b4: T79c0ff3Tffa657remTb4b4b4;
Tff7b72font-sizeTb4b4b4: T79c0ff0.8Tffa657remTb4b4b4;
Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--mutedTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72footer Tff7b72a Tb4b4b4{ Tff7b72colorTb4b4b4: Td2a8ffvarTb4b4b4(Te6edf3--accentTb4b4b4)Tb4b4b4; Tff7b72text-decorationTb4b4b4: Tff7b72noneTb4b4b4; Tb4b4b4}
Tff7b72footer Tff7b72aTb4b4b4:Tf0883ehover Tb4b4b4{ Tff7b72text-decorationTb4b4b4: Tff7b72underlineTb4b4b4; Tb4b4b4}
Tb4b4b4<Tb4b4b4/Tff7b72styleTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72headTb4b4b4>
Tb4b4b4<Tff7b72bodyTb4b4b4>
Tb4b4b4<Tff7b72mainTb4b4b4>
Tb4b4b4<Tff7b72headerTb4b4b4>
Tb4b4b4<Tff7b72h1Tb4b4b4>Tb4b4b4<Tff7b72spanTb4b4b4>RTTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>Node Firmware FlasherTb4b4b4<Tb4b4b4/Tff7b72h1Tb4b4b4>
Tb4b4b4<Tff7b72pTb4b4b4>Flash RTNode firmware directly from your browser Te6edf3&mdash; no Python or tools required.Tb4b4b4<Tb4b4b4/Tff7b72pTb4b4b4>
Tb4b4b4<Tff7b72pTb4b4b4>Tb4b4b4<Tff7b72strongTb4b4b4>Release track:Tb4b4b4<Tb4b4b4/Tff7b72strongTb4b4b4> All published firmware versions are labeled Tb4b4b4<Tff7b72strongTb4b4b4>BetaTb4b4b4<Tb4b4b4/Tff7b72strongTb4b4b4> and should be treated as lightly tested unless explicitly marked stable.Tb4b4b4<Tb4b4b4/Tff7b72pTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72headerTb4b4b4>

T8b949e<!-- Step 1: Detect -->
Tb4b4b4<Tff7b72section Te6edf3classTff7b72=Ta5d6ff"step"Tb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"step-label"Tb4b4b4>Step 1 Te6edf3&mdash; DetectTb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"flash-box"Tb4b4b4>
Tb4b4b4<Tff7b72pTb4b4b4>Connect your RTNode via USB, then click Tb4b4b4<Tff7b72strongTb4b4b4>DetectTb4b4b4<Tb4b4b4/Tff7b72strongTb4b4b4> to identify the board automatically.Tb4b4b4<Tb4b4b4/Tff7b72pTb4b4b4>
Tb4b4b4<Tff7b72button Te6edf3idTff7b72=Ta5d6ff"detect-btn" Te6edf3classTff7b72=Ta5d6ff"flash-btn"Tb4b4b4>DetectTb4b4b4<Tb4b4b4/Tff7b72buttonTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72sectionTb4b4b4>

T8b949e<!-- Step 2: Flash -->
Tb4b4b4<Tff7b72section Te6edf3classTff7b72=Ta5d6ff"step"Tb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"step-label"Tb4b4b4>Step 2 Te6edf3&mdash; FlashTb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"flash-box"Tb4b4b4>

T8b949e<!-- Version picker -->
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"version-row"Tb4b4b4>
Tb4b4b4<Tff7b72label Te6edf3forTff7b72=Ta5d6ff"version-select"Tb4b4b4>VersionTb4b4b4<Tb4b4b4/Tff7b72labelTb4b4b4>
Tb4b4b4<Tff7b72select Te6edf3idTff7b72=Ta5d6ff"version-select"Tb4b4b4>
Tb4b4b4<Tff7b72option Te6edf3valueTff7b72=Ta5d6ff"" Te6edf3disabled Te6edf3selectedTb4b4b4>Loading mirrored releases...Tb4b4b4<Tb4b4b4/Tff7b72optionTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72selectTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>

T8b949e<!-- Mode toggle -->
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"mode-toggle"Tb4b4b4>
Tb4b4b4<Tff7b72button Te6edf3classTff7b72=Ta5d6ff"mode-btn active" Te6edf3idTff7b72=Ta5d6ff"mode-update"Tb4b4b4>
Update firmware
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"mode-sub"Tb4b4b4>App only Te6edf3&mdash; settings preservedTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72buttonTb4b4b4>
Tb4b4b4<Tff7b72button Te6edf3classTff7b72=Ta5d6ff"mode-btn" Te6edf3idTff7b72=Ta5d6ff"mode-full"Tb4b4b4>
Full install
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"mode-sub"Tb4b4b4>Erases everything Te6edf3&mdash; bootloader Te6edf3&amp; all settingsTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72buttonTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>

Tb4b4b4<Tff7b72p Te6edf3idTff7b72=Ta5d6ff"flash-desc"Tb4b4b4>
Writes only the application region (0x10000).
Bootloader, partition table, and all saved settings (LoRa config, identity, WiFi) are left untouched.
Tb4b4b4<Tb4b4b4/Tff7b72pTb4b4b4>

Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"btn-row"Tb4b4b4>
Tb4b4b4<Tff7b72button Te6edf3idTff7b72=Ta5d6ff"flash-btn" Te6edf3classTff7b72=Ta5d6ff"flash-btn" Te6edf3disabledTb4b4b4>Flash FirmwareTb4b4b4<Tb4b4b4/Tff7b72buttonTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>

Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72sectionTb4b4b4>

T8b949e<!-- Console -->
Tb4b4b4<Tff7b72section Te6edf3classTff7b72=Ta5d6ff"step"Tb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"step-label"Tb4b4b4>ConsoleTb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3idTff7b72=Ta5d6ff"progress-wrap" Te6edf3classTff7b72=Ta5d6ff"progress-wrap" Te6edf3styleTff7b72=Ta5d6ff"display:none"Tb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"progress-track"Tb4b4b4>Tb4b4b4<Tff7b72div Te6edf3idTff7b72=Ta5d6ff"progress-fill" Te6edf3classTff7b72=Ta5d6ff"progress-fill"Tb4b4b4>Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3idTff7b72=Ta5d6ff"progress-pct" Te6edf3classTff7b72=Ta5d6ff"progress-pct"Tb4b4b4>0%Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3idTff7b72=Ta5d6ff"log-area" Te6edf3classTff7b72=Ta5d6ff"log-area" Te6edf3styleTff7b72=Ta5d6ff"display:none"Tb4b4b4>Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72sectionTb4b4b4>

T8b949e<!-- Result -->
Tb4b4b4<Tff7b72div Te6edf3idTff7b72=Ta5d6ff"detect-status" Te6edf3styleTff7b72=Ta5d6ff"display:none; margin-bottom: 2.2rem"Tb4b4b4>Tb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>

T8b949e<!-- Requirements -->
Tb4b4b4<Tff7b72section Te6edf3classTff7b72=Ta5d6ff"step"Tb4b4b4>
Tb4b4b4<Tff7b72div Te6edf3classTff7b72=Ta5d6ff"step-label"Tb4b4b4>RequirementsTb4b4b4<Tb4b4b4/Tff7b72divTb4b4b4>
Tb4b4b4<Tff7b72ul Te6edf3classTff7b72=Ta5d6ff"req-list"Tb4b4b4>
Tb4b4b4<Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"icon ok"Tb4b4b4>Te6edf3&#10003;Tb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>Google Chrome 89+ or Microsoft Edge Te6edf3&mdash; Web Serial API required
(Firefox and Safari are not supported)Tb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"icon ok"Tb4b4b4>Te6edf3&#10003;Tb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>USB cable connected to your RTNode deviceTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"icon ok"Tb4b4b4>Te6edf3&#10003;Tb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>No Python, esptool, or PlatformIO installation neededTb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72liTb4b4b4>
Tb4b4b4<Tff7b72span Te6edf3classTff7b72=Ta5d6ff"icon warn"Tb4b4b4>Te6edf3&#9888;Tb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tff7b72spanTb4b4b4>On Linux, you may need to add your user to the Tb4b4b4<Tff7b72codeTb4b4b4>dialoutTb4b4b4<Tb4b4b4/Tff7b72codeTb4b4b4>
group: Tb4b4b4<Tff7b72codeTb4b4b4>sudo usermod -a -G dialout $USERTb4b4b4<Tb4b4b4/Tff7b72codeTb4b4b4> (then log out and
back in)Tb4b4b4<Tb4b4b4/Tff7b72spanTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72liTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72ulTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72sectionTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72mainTb4b4b4>

Tb4b4b4<Tff7b72footerTb4b4b4>
Tb4b4b4<Tff7b72pTb4b4b4>
RTNode Firmware Te6edf3&mdash;
Tb4b4b4<Tff7b72a Te6edf3hrefTff7b72=Ta5d6ff"https://github.com/jrl290/RTNode-HeltecV4" Te6edf3targetTff7b72=Ta5d6ff"_blank" Te6edf3relTff7b72=Ta5d6ff"noopener"Tb4b4b4>
GitHub
Tb4b4b4<Tb4b4b4/Tff7b72aTb4b4b4>
Te6edf3&middot;
Powered by
Tb4b4b4<Tff7b72a Te6edf3hrefTff7b72=Ta5d6ff"https://github.com/espressif/esptool-js" Te6edf3targetTff7b72=Ta5d6ff"_blank" Te6edf3relTff7b72=Ta5d6ff"noopener"Tb4b4b4>
esptool-js
Tb4b4b4<Tb4b4b4/Tff7b72aTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72pTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72footerTb4b4b4>

Tb4b4b4<Tff7b72script Te6edf3typeTff7b72=Ta5d6ff"module"Tb4b4b4>
Tff7b72import Tb4b4b4{ Te6edf3ESPLoaderTb4b4b4, Te6edf3Transport Tb4b4b4} Tff7b72from Ta5d6ff'https://unpkg.com/esptool-js@0.4.6/bundle.js'Tb4b4b4;

T8b949e// ── Firmware config ────────────────────────────────────────────────────────
Tff7b72const Te6edf3REPO Tff7b72= Ta5d6ff'jrl290/RTNode-HeltecV4'Tb4b4b4;
Tff7b72const Te6edf3FIRMWARE Tff7b72= Tb4b4b4{
Te6edf3v4Tff7b72: Tb4b4b4{
Te6edf3labelTff7b72: Ta5d6ff'Heltec V4 (PSRAM, QIO)'Tb4b4b4,
Te6edf3updateNameTff7b72: Ta5d6ff'rtnode_heltec_v4.bin'Tb4b4b4,
Te6edf3fullNameTff7b72: Ta5d6ff'rtnode_heltec_v4_merged.bin'Tb4b4b4,
Te6edf3updateAddrTff7b72: T79c0ff0x10000Tb4b4b4,
Te6edf3fullAddrTff7b72: T79c0ff0x0Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Te6edf3v3Tff7b72: Tb4b4b4{
Te6edf3labelTff7b72: Ta5d6ff'Heltec V3 (DIO)'Tb4b4b4,
Te6edf3updateNameTff7b72: Ta5d6ff'rtnode_heltec_v3.bin'Tb4b4b4,
Te6edf3fullNameTff7b72: Ta5d6ff'rtnode_heltec_v3_merged.bin'Tb4b4b4,
Te6edf3updateAddrTff7b72: T79c0ff0x10000Tb4b4b4,
Te6edf3fullAddrTff7b72: T79c0ff0x0Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;

T8b949e// Tracks which assets are mirrored for each released version (from versions.json).
T8b949e// Older releases live under firmware/<tag>/ because GitHub's release-download
T8b949e// URLs do not expose CORS headers and so cannot be fetched from the browser.
T8b949e// Run docs/mirror_releases.py to refresh the mirror.
Tff7b72const Te6edf3RELEASE_CHANNEL Tff7b72= Ta5d6ff'Beta'Tb4b4b4;
Tff7b72const Te6edf3versionAssets Tff7b72= Tff7b72new Tffa657MapTb4b4b4(Tb4b4b4)Tb4b4b4;

Tff7b72function Te6edf3formatReleaseLabelTb4b4b4(Te6edf3tagTb4b4b4, Te6edf3nameTb4b4b4, Te6edf3stabilityTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3channel Tff7b72= Te6edf3stability Tff7b72? Tffa657StringTb4b4b4(Te6edf3stabilityTb4b4b4) Tff7b72: Te6edf3RELEASE_CHANNELTb4b4b4;
Tff7b72const Te6edf3base Tff7b72= Ta5d6ff`Tffd700${Te6edf3tagTffd700}Tffd700${Te6edf3name Tff7b72&& Te6edf3name Tff7b72!== Te6edf3tag Tff7b72? Ta5d6ff' — ' Tff7b72+ Te6edf3name Tff7b72: Ta5d6ff''Tffd700}Ta5d6ff`Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3baseTb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3includesTb4b4b4(Te6edf3channelTb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3baseTb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff`Tffd700${Te6edf3baseTffd700}Ta5d6ff (Tffd700${Te6edf3channelTffd700}Ta5d6ff)Ta5d6ff`Tb4b4b4;
Tb4b4b4}

Tff7b72function Te6edf3getBinUrlTb4b4b4(Te6edf3fwTb4b4b4, Te6edf3isUpdateTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3name Tff7b72= Te6edf3isUpdate Tff7b72? Te6edf3fwTb4b4b4.Te6edf3updateName Tff7b72: Te6edf3fwTb4b4b4.Te6edf3fullNameTb4b4b4;
Tff7b72const Te6edf3ver Tff7b72= Te6edf3versionSelectTb4b4b4.Te6edf3valueTb4b4b4;
Tff7b72return Ta5d6ff`Ta5d6fffirmware/Tffd700${Te6edf3verTffd700}Ta5d6ff/Tffd700${Te6edf3nameTffd700}Ta5d6ff`Tb4b4b4;
Tb4b4b4}

Tff7b72function Te6edf3assetAvailableTb4b4b4(Te6edf3verTb4b4b4, Te6edf3nameTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3set Tff7b72= Te6edf3versionAssetsTb4b4b4.Te6edf3getTb4b4b4(Te6edf3verTb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72!Tff7b72!Tb4b4b4(Te6edf3set Tff7b72&& Te6edf3setTb4b4b4.Te6edf3hasTb4b4b4(Te6edf3nameTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}

T8b949e// ── Load mirrored release versions from versions.json ─────────────────────
Tb4b4b4(Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3res Tff7b72= Tff7b72await Te6edf3fetchTb4b4b4(Ta5d6ff'firmware/versions.json'Tb4b4b4, Tb4b4b4{ Te6edf3cacheTff7b72: Ta5d6ff'no-cache' Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3resTb4b4b4.Te6edf3okTb4b4b4) Tb4b4b4{
Te6edf3versionSelectTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff'<option value="" disabled selected>No mirrored releases found</option>'Tb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3versions Tff7b72= Tff7b72await Te6edf3resTb4b4b4.Te6edf3jsonTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff''Tb4b4b4;
Tff7b72let Te6edf3count Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3v Tff7b72of Te6edf3versionsTb4b4b4) Tb4b4b4{
Te6edf3versionAssetsTb4b4b4.Te6edf3setTb4b4b4(Te6edf3vTb4b4b4.Te6edf3tagTb4b4b4, Tff7b72new Tffa657SetTb4b4b4(Te6edf3vTb4b4b4.Te6edf3assets Tff7b72|| Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3opt Tff7b72= Tffa657documentTb4b4b4.Te6edf3createElementTb4b4b4(Ta5d6ff'option'Tb4b4b4)Tb4b4b4;
Te6edf3optTb4b4b4.Te6edf3value Tff7b72= Te6edf3vTb4b4b4.Te6edf3tagTb4b4b4;
Te6edf3optTb4b4b4.Te6edf3textContent Tff7b72= Te6edf3formatReleaseLabelTb4b4b4(Te6edf3vTb4b4b4.Te6edf3tagTb4b4b4, Te6edf3vTb4b4b4.Te6edf3nameTb4b4b4, Te6edf3vTb4b4b4.Te6edf3stabilityTb4b4b4)Tb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3appendChildTb4b4b4(Te6edf3optTb4b4b4)Tb4b4b4;
Te6edf3countTff7b72++Tb4b4b4;
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3count Tff7b72=== T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3versionSelectTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff'<option value="" disabled selected>No mirrored releases found</option>'Tb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3versionSelectTb4b4b4.Te6edf3selectedIndex Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3_Tb4b4b4) Tb4b4b4{
Te6edf3versionSelectTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff'<option value="" disabled selected>No mirrored releases found</option>'Tb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4(Tb4b4b4)Tb4b4b4;

T8b949e// ── Detection — mirrors detect_board() in flash.py ─────────────────────────
Tff7b72function Te6edf3detectBoardTb4b4b4(Te6edf3chipNameTb4b4b4, Te6edf3featuresTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3chipNameTb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff'ESP32-S3'Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3hasPsram Tff7b72= Te6edf3featuresTb4b4b4.Te6edf3someTb4b4b4(Te6edf3f Tb4b4b4=> Tffa657StringTb4b4b4(Te6edf3fTb4b4b4)Tb4b4b4.Te6edf3toUpperCaseTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3includesTb4b4b4(Ta5d6ff'PSRAM'Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3hasPsram Tff7b72? Ta5d6ff'v4' Tff7b72: Ta5d6ff'v3'Tb4b4b4;
Tb4b4b4}
Tff7b72return Ta5d6ff'v3'Tb4b4b4;
Tb4b4b4}

T8b949e// ── UI refs ────────────────────────────────────────────────────────────────
Tff7b72const Te6edf3detectBtn Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'detect-btn'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3flashBtn Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'flash-btn'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3versionSelect Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'version-select'Tb4b4b4)Tb4b4b4;

Tff7b72const Te6edf3flashDesc Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'flash-desc'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3modeUpdate Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'mode-update'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3modeFull Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'mode-full'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3detectStatus Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'detect-status'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3progressWrap Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'progress-wrap'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3progressFill Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'progress-fill'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3progressPct Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'progress-pct'Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3logArea Tff7b72= Tffa657documentTb4b4b4.Te6edf3getElementByIdTb4b4b4(Ta5d6ff'log-area'Tb4b4b4)Tb4b4b4;

Tff7b72let Te6edf3currentIsUpdate Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72let Te6edf3transport Tff7b72= Tff7b72nullTb4b4b4;
Tff7b72let Te6edf3loader Tff7b72= Tff7b72nullTb4b4b4;
Tff7b72let Te6edf3detectedFw Tff7b72= Tff7b72nullTb4b4b4;

Tff7b72const Te6edf3UPDATE_DESC Tff7b72= Ta5d6ff'Writes only the application region (0x10000). ' Tff7b72+
Ta5d6ff'Bootloader, partition table, and all saved settings (LoRa config, identity, WiFi) are left untouched.'Tb4b4b4;
Tff7b72const Te6edf3FULL_DESC Tff7b72= Ta5d6ff'\u26A0\uFE0F Writes the full image from offset 0x0 and erases the entire flash first. ' Tff7b72+
Ta5d6ff'Bootloader, partition table, app, and all saved settings will be wiped. ' Tff7b72+
Ta5d6ff'Use for first-time installs or when the partition layout has changed.'Tb4b4b4;

Te6edf3modeUpdateTb4b4b4.Te6edf3addEventListenerTb4b4b4(Ta5d6ff'click'Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3modeUpdateTb4b4b4.Te6edf3classListTb4b4b4.Te6edf3addTb4b4b4(Ta5d6ff'active'Tb4b4b4)Tb4b4b4; Te6edf3modeFullTb4b4b4.Te6edf3classListTb4b4b4.Te6edf3removeTb4b4b4(Ta5d6ff'active'Tb4b4b4)Tb4b4b4;
Te6edf3currentIsUpdate Tff7b72= Tff7b72trueTb4b4b4; Te6edf3flashDescTb4b4b4.Te6edf3textContent Tff7b72= Te6edf3UPDATE_DESCTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3modeFullTb4b4b4.Te6edf3addEventListenerTb4b4b4(Ta5d6ff'click'Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3modeFullTb4b4b4.Te6edf3classListTb4b4b4.Te6edf3addTb4b4b4(Ta5d6ff'active'Tb4b4b4)Tb4b4b4; Te6edf3modeUpdateTb4b4b4.Te6edf3classListTb4b4b4.Te6edf3removeTb4b4b4(Ta5d6ff'active'Tb4b4b4)Tb4b4b4;
Te6edf3currentIsUpdate Tff7b72= Tff7b72falseTb4b4b4; Te6edf3flashDescTb4b4b4.Te6edf3textContent Tff7b72= Te6edf3FULL_DESCTb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

T8b949e// ── Helpers ────────────────────────────────────────────────────────────────
Tff7b72function Te6edf3logTb4b4b4(Te6edf3msgTb4b4b4) Tb4b4b4{
Te6edf3logAreaTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'block'Tb4b4b4;
Te6edf3logAreaTb4b4b4.Te6edf3textContent Tff7b72+= Te6edf3msg Tff7b72+ Ta5d6ff'\n'Tb4b4b4;
Te6edf3logAreaTb4b4b4.Te6edf3scrollTop Tff7b72= Te6edf3logAreaTb4b4b4.Te6edf3scrollHeightTb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3setBadgeTb4b4b4(Te6edf3kindTb4b4b4, Te6edf3htmlTb4b4b4) Tb4b4b4{
Te6edf3detectStatusTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'block'Tb4b4b4;
Te6edf3detectStatusTb4b4b4.Te6edf3innerHTML Tff7b72= Ta5d6ff`Ta5d6ff<div class="detect-badge Tffd700${Te6edf3kindTffd700}Ta5d6ff">Tffd700${Te6edf3htmlTffd700}Ta5d6ff</div>Ta5d6ff`Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3setProgressTb4b4b4(Te6edf3pctTb4b4b4) Tb4b4b4{
Te6edf3progressWrapTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'block'Tb4b4b4;
Te6edf3progressFillTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3width Tff7b72= Te6edf3pct Tff7b72+ Ta5d6ff'%'Tb4b4b4;
Te6edf3progressPctTb4b4b4.Te6edf3textContent Tff7b72= Tffa657MathTb4b4b4.Te6edf3roundTb4b4b4(Te6edf3pctTb4b4b4) Tff7b72+ Ta5d6ff'%'Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3makeTerminalTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4{
Te6edf3cleanTb4b4b4(Tb4b4b4) Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3writeLineTb4b4b4(Te6edf3dataTb4b4b4) Tb4b4b4{ Te6edf3logTb4b4b4(Te6edf3dataTb4b4b4)Tb4b4b4; Tb4b4b4}Tb4b4b4,
Te6edf3writeTb4b4b4(Te6edf3dataTb4b4b4) Tb4b4b4{ Tff7b72if Tb4b4b4(Te6edf3dataTb4b4b4.Te6edf3trimTb4b4b4(Tb4b4b4)Tb4b4b4) Te6edf3logTb4b4b4(Te6edf3dataTb4b4b4.Te6edf3trimTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4; Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72async Tff7b72function Te6edf3doDisconnectTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3transportTb4b4b4) Tb4b4b4{ Tff7b72try Tb4b4b4{ Tff7b72await Te6edf3transportTb4b4b4.Te6edf3disconnectTb4b4b4(Tb4b4b4)Tb4b4b4; Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3_Tb4b4b4) Tb4b4b4{Tb4b4b4} Te6edf3transport Tff7b72= Tff7b72nullTb4b4b4; Tb4b4b4}
Te6edf3loader Tff7b72= Tff7b72nullTb4b4b4; Te6edf3detectedFw Tff7b72= Tff7b72nullTb4b4b4;
Tb4b4b4}

T8b949e// ── Step 1: Detect ─────────────────────────────────────────────────────────
Te6edf3detectBtnTb4b4b4.Te6edf3addEventListenerTb4b4b4(Ta5d6ff'click'Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Tb4b4b4(Ta5d6ff'serial' Tff7b72in Te6edf3navigatorTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3setBadgeTb4b4b4(Ta5d6ff'err'Tb4b4b4, Ta5d6ff'&#10007; Web Serial not supported &mdash; use Chrome or Edge'Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Tff7b72await Te6edf3doDisconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3flashBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3progressWrapTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'none'Tb4b4b4;
Te6edf3logAreaTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'none'Tb4b4b4; Te6edf3logAreaTb4b4b4.Te6edf3textContent Tff7b72= Ta5d6ff''Tb4b4b4;
Te6edf3detectStatusTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'none'Tb4b4b4;
Te6edf3detectBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;

Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3port Tff7b72= Tff7b72await Te6edf3navigatorTb4b4b4.Te6edf3serialTb4b4b4.Te6edf3requestPortTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3transport Tff7b72= Tff7b72new Te6edf3TransportTb4b4b4(Te6edf3portTb4b4b4, Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3setBadgeTb4b4b4(Ta5d6ff'info'Tb4b4b4, Ta5d6ff'&#9881; Connecting&hellip;'Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff'Connecting to device...'Tb4b4b4)Tb4b4b4;

Te6edf3loader Tff7b72= Tff7b72new Te6edf3ESPLoaderTb4b4b4(Tb4b4b4{ Te6edf3transportTb4b4b4, Te6edf3baudrateTff7b72: T79c0ff921600Tb4b4b4, Te6edf3terminalTff7b72: Te6edf3makeTerminalTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3mainTb4b4b4(Ta5d6ff'default_reset'Tb4b4b4)Tb4b4b4;

Tff7b72const Te6edf3chipName Tff7b72= Te6edf3loaderTb4b4b4.Te6edf3chipTb4b4b4.Te6edf3CHIP_NAMETb4b4b4;
Tff7b72const Te6edf3features Tff7b72= Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3chipTb4b4b4.Te6edf3getChipFeaturesTb4b4b4(Te6edf3loaderTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3flashSizeKb Tff7b72= Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3getFlashSizeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3flashSize Tff7b72= Te6edf3flashSizeKb Tff7b72>= T79c0ff1024 Tff7b72? Tb4b4b4(Te6edf3flashSizeKb Tff7b72/ T79c0ff1024Tb4b4b4) Tff7b72+ Ta5d6ff'MB' Tff7b72: Te6edf3flashSizeKb Tff7b72+ Ta5d6ff'KB'Tb4b4b4;
Tff7b72const Te6edf3boardKey Tff7b72= Te6edf3detectBoardTb4b4b4(Te6edf3chipNameTb4b4b4, Te6edf3featuresTb4b4b4)Tb4b4b4;
Te6edf3detectedFw Tff7b72= Te6edf3FIRMWARETb4b4b4[Te6edf3boardKeyTb4b4b4]Tb4b4b4;

T8b949e// Extra diagnostics — helpful when triaging boot-loop reports.
T8b949e// readFlashId() returns 24 bits: low byte = JEDEC manufacturer,
T8b949e// upper 16 bits = device ID (memory type + capacity).
Tff7b72let Te6edf3chipDesc Tff7b72= Te6edf3chipNameTb4b4b4;
Tff7b72let Te6edf3flashIdHex Tff7b72= Ta5d6ff'?'Tb4b4b4;
Tff7b72try Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72typeof Te6edf3loaderTb4b4b4.Te6edf3chipTb4b4b4.Te6edf3getChipDescription Tff7b72=== Ta5d6ff'function'Tb4b4b4) Tb4b4b4{
Te6edf3chipDesc Tff7b72= Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3chipTb4b4b4.Te6edf3getChipDescriptionTb4b4b4(Te6edf3loaderTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3_Tb4b4b4) Tb4b4b4{Tb4b4b4}
Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3fid Tff7b72= Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3readFlashIdTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3mfg Tff7b72= Te6edf3fid Tff7b72& T79c0ff0xffTb4b4b4;
Tff7b72const Te6edf3dev Tff7b72= Tb4b4b4(Te6edf3fid Tff7b72>> T79c0ff8Tb4b4b4) Tff7b72& T79c0ff0xffffTb4b4b4;
Te6edf3flashIdHex Tff7b72= Ta5d6ff`Ta5d6ffmfg=0xTffd700${Te6edf3mfgTb4b4b4.Te6edf3toStringTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4.Te6edf3padStartTb4b4b4(T79c0ff2Tb4b4b4, Ta5d6ff'0'Tb4b4b4)Tffd700}Ta5d6ff dev=0xTffd700${Te6edf3devTb4b4b4.Te6edf3toStringTb4b4b4(T79c0ff16Tb4b4b4)Tb4b4b4.Te6edf3padStartTb4b4b4(T79c0ff4Tb4b4b4, Ta5d6ff'0'Tb4b4b4)Tffd700}Ta5d6ff`Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3_Tb4b4b4) Tb4b4b4{Tb4b4b4}

Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffChip: Tffd700${Te6edf3chipNameTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffVariant: Tffd700${Te6edf3chipDescTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffFeatures: Tffd700${Te6edf3featuresTb4b4b4.Te6edf3joinTb4b4b4(Ta5d6ff', 'Tb4b4b4)Tffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffFlash size: Tffd700${Te6edf3flashSizeTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffFlash ID: Tffd700${Te6edf3flashIdHexTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffBoard: Tffd700${Te6edf3detectedFwTb4b4b4.Te6edf3labelTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;

Te6edf3setBadgeTb4b4b4(Ta5d6ff'ok'Tb4b4b4, Ta5d6ff`Ta5d6ff&#10003; Tffd700${Te6edf3detectedFwTb4b4b4.Te6edf3labelTffd700}Ta5d6ff &mdash; Flash: Tffd700${Te6edf3flashSizeTffd700}Ta5d6ff &mdash; Ready to flashTa5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3flashBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3errTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Te6edf3err Tff7b72instanceof Tf85149Error Tff7b72? Te6edf3errTb4b4b4.Te6edf3message Tff7b72: Tffa657StringTb4b4b4(Te6edf3errTb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff'Error: ' Tff7b72+ Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3setBadgeTb4b4b4(Ta5d6ff'err'Tb4b4b4, Ta5d6ff'&#10007; ' Tff7b72+ Te6edf3msgTb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3doDisconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3detectBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;

T8b949e// ── Step 2: Flash ──────────────────────────────────────────────────────────
Te6edf3flashBtnTb4b4b4.Te6edf3addEventListenerTb4b4b4(Ta5d6ff'click'Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3loader Tff7b72|| Tff7b72!Te6edf3detectedFwTb4b4b4) Tb4b4b4{
Te6edf3setBadgeTb4b4b4(Ta5d6ff'err'Tb4b4b4, Ta5d6ff'&#10007; Detect your device first (Step 1).'Tb4b4b4)Tb4b4b4;
Tff7b72returnTb4b4b4;
Tb4b4b4}
Te6edf3flashBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3detectBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3progressFillTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3width Tff7b72= Ta5d6ff'0%'Tb4b4b4;
Te6edf3progressWrapTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'none'Tb4b4b4;
Te6edf3logAreaTb4b4b4.Te6edf3textContent Tff7b72= Ta5d6ff''Tb4b4b4; Te6edf3logAreaTb4b4b4.Te6edf3styleTb4b4b4.Te6edf3display Tff7b72= Ta5d6ff'block'Tb4b4b4;

Tff7b72try Tb4b4b4{
Tff7b72const Te6edf3fw Tff7b72= Te6edf3detectedFwTb4b4b4;
Tff7b72const Te6edf3ver Tff7b72= Te6edf3versionSelectTb4b4b4.Te6edf3valueTb4b4b4;
Tff7b72const Te6edf3assetName Tff7b72= Te6edf3currentIsUpdate Tff7b72? Te6edf3fwTb4b4b4.Te6edf3updateName Tff7b72: Te6edf3fwTb4b4b4.Te6edf3fullNameTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3assetAvailableTb4b4b4(Te6edf3verTb4b4b4, Te6edf3assetNameTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3other Tff7b72= Te6edf3currentIsUpdate Tff7b72? Ta5d6ff'Full install' Tff7b72: Ta5d6ff'Update firmware'Tb4b4b4;
Tff7b72throw Tff7b72new Tf85149ErrorTb4b4b4(
Ta5d6ff`Tffd700${Te6edf3RELEASE_CHANNELTffd700}Ta5d6ff release Tffd700${Te6edf3verTffd700}Ta5d6ff does not include Tffd700${Te6edf3assetNameTffd700}Ta5d6ff. Ta5d6ff` Tff7b72+
Ta5d6ff`Ta5d6ffTry the "Tffd700${Te6edf3otherTffd700}Ta5d6ff" mode, or pick a different version.Ta5d6ff`
Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72const Te6edf3binUrl Tff7b72= Te6edf3getBinUrlTb4b4b4(Te6edf3fwTb4b4b4, Te6edf3currentIsUpdateTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3addr Tff7b72= Te6edf3currentIsUpdate Tff7b72? Te6edf3fwTb4b4b4.Te6edf3updateAddr Tff7b72: Te6edf3fwTb4b4b4.Te6edf3fullAddrTb4b4b4;

Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffVersion: Tffd700${Te6edf3verTffd700}Ta5d6ff (Tffd700${Te6edf3RELEASE_CHANNELTffd700}Ta5d6ff)Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffMode: Tffd700${Te6edf3currentIsUpdate Tff7b72? Ta5d6ff'Update (app only, settings preserved)' Tff7b72: Ta5d6ff'Full install (erase all)'Tffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffFirmware: Tffd700${Te6edf3binUrlTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3resp Tff7b72= Tff7b72await Te6edf3fetchTb4b4b4(Te6edf3binUrlTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3respTb4b4b4.Te6edf3okTb4b4b4) Tff7b72throw Tff7b72new Tf85149ErrorTb4b4b4(Ta5d6ff`Ta5d6ffFailed to fetch firmware: Tffd700${Te6edf3respTb4b4b4.Te6edf3statusTffd700}Ta5d6ff Tffd700${Te6edf3respTb4b4b4.Te6edf3statusTextTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;

T8b949e// esptool-js writeFlash requires a binary string, not Uint8Array
Tff7b72const Te6edf3bytes Tff7b72= Tff7b72new Tffa657Uint8ArrayTb4b4b4(Tff7b72await Te6edf3respTb4b4b4.Te6edf3arrayBufferTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3binData Tff7b72= Tffa657ArrayTb4b4b4.Tff7b72fromTb4b4b4(Te6edf3bytesTb4b4b4, Te6edf3b Tb4b4b4=> Tffa657StringTb4b4b4.Te6edf3fromCharCodeTb4b4b4(Te6edf3bTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3joinTb4b4b4(Ta5d6ff''Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff`Ta5d6ffSize: Tffd700${Te6edf3bytesTb4b4b4.Te6edf3lengthTb4b4b4.Te6edf3toLocaleStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff bytesTa5d6ff`Tb4b4b4)Tb4b4b4;

Te6edf3logTb4b4b4(Ta5d6ff'Flashing...'Tb4b4b4)Tb4b4b4;
Te6edf3setProgressTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3writeFlashTb4b4b4(Tb4b4b4{
Te6edf3fileArrayTff7b72: Tb4b4b4[Tb4b4b4{ Te6edf3dataTff7b72: Te6edf3binDataTb4b4b4, Te6edf3addressTff7b72: Te6edf3addr Tb4b4b4}Tb4b4b4]Tb4b4b4,
Te6edf3flashSizeTff7b72: Ta5d6ff'keep'Tb4b4b4,
Te6edf3flashModeTff7b72: Ta5d6ff'keep'Tb4b4b4,
Te6edf3flashFreqTff7b72: Ta5d6ff'keep'Tb4b4b4,
Te6edf3eraseAllTff7b72: Tff7b72!Te6edf3currentIsUpdateTb4b4b4,
Te6edf3compressTff7b72: Tff7b72trueTb4b4b4,
Te6edf3reportProgressTb4b4b4(Te6edf3_idxTb4b4b4, Te6edf3writtenTb4b4b4, Te6edf3totalTb4b4b4) Tb4b4b4{
Te6edf3setProgressTb4b4b4(Tb4b4b4(Te6edf3written Tff7b72/ Te6edf3totalTb4b4b4) Tff7b72* T79c0ff100Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3setProgressTb4b4b4(T79c0ff100Tb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff'Flash complete. Rebooting...'Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3loaderTb4b4b4.Te6edf3hardResetTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setBadgeTb4b4b4(Ta5d6ff'ok'Tb4b4b4, Ta5d6ff'&#10003; Done! Device is rebooting.'Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3doDisconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3errTb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Te6edf3err Tff7b72instanceof Tf85149Error Tff7b72? Te6edf3errTb4b4b4.Te6edf3message Tff7b72: Tffa657StringTb4b4b4(Te6edf3errTb4b4b4)Tb4b4b4;
Te6edf3logTb4b4b4(Ta5d6ff'Error: ' Tff7b72+ Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3setBadgeTb4b4b4(Ta5d6ff'err'Tb4b4b4, Ta5d6ff'&#10007; ' Tff7b72+ Te6edf3msgTb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3doDisconnectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3detectBtnTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3versionSelectTb4b4b4.Te6edf3disabled Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3flashBtnTb4b4b4.Te6edf3disabled Tff7b72= Tb4b4b4(Te6edf3loader Tff7b72=== Tff7b72nullTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4<Tb4b4b4/Tff7b72scriptTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72bodyTb4b4b4>
Tb4b4b4<Tb4b4b4/Tff7b72htmlTb4b4b4>

Served by rngit 1.4.2 - Generated in 0.15s